package com.zero;

import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 系统日志切面
 */
@Aspect  // 使用@Aspect注解声明一个切面
@Component
@Log4j2
public class LogAspect {
    private Map<Object, Object> dataMap = new LinkedHashMap<>();
    @Autowired
    private HttpServletRequest request;

    //表示匹配com.savage.server包及其子包下的所有方法
//    @Pointcut("execution(* com.wsh.zero.controller..*.*(..))")
    @Pointcut("@annotation(com.zero.LogTag)")
    public void Pointcut() {
    }


//    //前置通知
//    @Before("Pointcut()")
//    public void beforeMethod(JoinPoint joinPoint) {
//        System.out.println("调用了前置通知");
//
//    }
//
//    //@After: 后置通知
//    @After("Pointcut()")
//    public void afterMethod(JoinPoint joinPoint) {
//        System.out.println("调用了后置通知");
//    }
//
//    //@AfterRunning: 返回通知 rsult为返回内容
//    @AfterReturning(value = "Pointcut()", returning = "result")
//    public void afterReturningMethod(JoinPoint joinPoint, Object result) {
//        System.out.println("调用了返回通知");
//    }

    //@AfterThrowing: 异常通知
    @AfterThrowing(value = "Pointcut()", throwing = "e")
    public void afterReturningMethod(JoinPoint joinPoint, Exception e) {
        //当controller没有捕获到异常时会进入
        System.out.println("=====进入异常日志类======");

    }

    //@Around：环绕通知
    @Around("Pointcut()")
    public Object Around(ProceedingJoinPoint pjp) throws Throwable {
        setEntity(pjp);
        Object object = pjp.proceed();
        return object;
    }


    public void setEntity(JoinPoint pjp) {
        String classMethod = pjp.getTarget().getClass().getName() + "." + pjp.getSignature().getName();
        //获取传入目标方法的参数
        Object[] args = pjp.getArgs();
        StringBuilder params = new StringBuilder();
        for (int i = 0; i < args.length; i++) {
            params.append(args[i]);
            if (i < args.length - 1) {
                params.append(",");
            }
        }
        dataMap.put("params", params);
    }
}
